from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from ui.main import Ui_MainWindow

# from fabric.api import *
# from fabric.context_managers import *
# from fabric.contrib.console import confirm
# from fabric.colors import *
# # fabric全局变量
# env.hosts = ['192.168.1.150']
# env.user = 'pi'
# env.port = 22
# env.password = 'raspberry'
# local_path = './packages'
# remote_path = '/home/pi/fsc-system'

from fsc import *

import os
import time
import json
import logging
import threading
import subprocess
import configparser

# filename = '%s/log/%s.log' % (os.getcwd(),
#                               time.strftime("%Y%m%d", time.localtime()))
logging.basicConfig(level=logging.INFO,  # 控制台打印的日志级别
                    # filename=filename,
                    # filemode='a',  # 模式，有w和a，w就是写模式，每次都会重新写日志，覆盖之前的日志
                    format='%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s'
                    )
logger = logging.getLogger(__name__)


class MainWindow(QMainWindow, Ui_MainWindow):

    local_path = ''
    signal_txt = pyqtSignal(str)

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)
        # self.setWindowState(Qt.WindowMaximized)
        self.setWindowIcon(QIcon(':icons/images_rc/app.png'))
        self.setWindowTitle("辐射场升级软件")
        self.setFixedSize(1500, 600)

        self.pushButton_upgrade_select.clicked.connect(self.selectDir)
        self.pushButton_upgrade_start.clicked.connect(self.upgrade)
        self.signal_txt.connect(self.showInfo)

    def showInfo(self, text):
        self.textBrowser.append(text)

    def enableBtn(self, enable):
        self.pushButton_dir.setEnabled(enable)
        self.pushButton_up_all.setEnabled(enable)
        self.pushButton_up_web.setEnabled(enable)
        self.pushButton_up_server.setEnabled(enable)

    def selectDir(self):
        res = QFileDialog.getExistingDirectory(self, "选择升级文件夹", "./")
        if res != '':
            self.local_path = res
            self.textBrowser.clear()
            self.textBrowser.append(self.local_path)
            self.readVersion()
            self.lineEdit_local_path.setText(self.local_path)
            # self.writeConfig(host=self.lineEdit_upgrade_ip.text(),
            #                  port=self.lineEdit_upgrade_port.text(),
            #                  user=self.lineEdit_upgrade_username.text(),
            #                  password=self.lineEdit_upgrade_password.text(),
            #                  local_path=self.local_path,
            #                  remote_path='/home/pi/fsc-system')

    def upgrade(self, t):
        # if self.label_content.text() == '':
        #     QMessageBox.warning(self, "提示", "请选择正确的升级包文件夹", QMessageBox.Yes)
        #     return  
        # if self.local_path == '':
        #     QMessageBox.warning(self, "提示", "请选择正确的升级包文件夹", QMessageBox.Yes)
        #     return 
        # self.upgrade_type = t
        # 写入配置文件
        self.writeConfig(host=self.lineEdit_upgrade_ip.text(),
                         port=self.lineEdit_upgrade_port.text(),
                         user=self.lineEdit_upgrade_username.text(),
                         password=self.lineEdit_upgrade_password.text(),
                         local_path=self.lineEdit_local_path.text(),
                         remote_path=self.lineEdit_remote_path.text())
        self.t1 = threading.Thread(target=self.upgradeThread)
        self.t1.setDaemon(True)
        self.t1.start()

    def upgradeThread(self):
        self.signal_txt.emit("开始升级...")
        t = self.comboBox_upgrade_type.currentIndex()
        print(t)
        path = os.getcwd()
        if t == 0:
            print("only upgrade web!!!")
            self.signal_txt.emit("升级网页中，请等待升级完成...")
            execute(web)
            cmd = '"%s/fab.exe" -f "%s/fsc.py" web' % (path, path)
        if t == 1:
            self.signal_txt.emit("升级后台中，请等待升级完成...")
            execute(server)
            cmd = '"%s/fab.exe" -f "%s/fsc.py" server' % (path, path)
        if t == 2:
            self.signal_txt.emit("升级数据库中，请等待升级完成...")
            execute(mysql)
            cmd = '"%s/fab.exe" -f "%s/fsc.py" mysql' % (path, path)
        if t == 3:
            self.signal_txt.emit("升级emqx中，请等待升级完成...")
            execute(emqx)
            cmd = '"%s/fab.exe" -f "%s/fsc.py" emqx' % (path, path)
        if t == 4:
            self.signal_txt.emit("更新docker文件，请等待升级完成...")
            execute(docker)
            cmd = '"%s/fab.exe" -f "%s/fsc.py" docker' % (path, path)
        if t == 5:
            self.signal_txt.emit("整体升级中，请等待升级完成...")
            execute(up_all)
            cmd = '"%s/fab.exe" -f "%s/fsc.py" up_all' % (path, path)
        self.signal_txt.emit("升级完成!")
        # logger.info('return code:', return_code, 'data:', data)

    def run(self, cmd, shell=False) -> (int, str):
        """
        开启子进程，执行对应指令，控制台打印执行过程，然后返回子进程执行的状态码和执行返回的数据
        :param cmd: 子进程命令
        :param shell: 是否开启shell
        :return: 子进程状态码和执行结果
        """
        self.signal_txt.emit(
            '\033[1;32m************** START **************\033[0m')
        p = subprocess.Popen(
            cmd, shell=shell, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        result = []
        while p.poll() is None:
            line = p.stdout.readline().strip()
            if line:
                line = self._decode_data(line)
                result.append(line)
                self.signal_txt.emit(line)
                # print('\033[1;35m{0}\033[0m'.format(line))
            # 清空缓存
            sys.stdout.flush()
            sys.stderr.flush()
        # 判断返回码状态
        if p.returncode == 0:
            self.signal_txt.emit(
                '\033[1;32m************** SUCCESS **************\033[0m')
        else:
            self.signal_txt.emit(
                '\033[1;31m************** FAILED **************\033[0m')
        return p.returncode, '\r\n'.join(result)

    def _decode_data(self, byte_data: bytes):
        """
        解码数据
        :param byte_data: 待解码数据
        :return: 解码字符串
        """
        try:
            return byte_data.decode('UTF-8')
        except UnicodeDecodeError:
            return byte_data.decode('GB18030')

    def readVersion(self):
        try:
            with open("%s/version.txt" % self.local_path, "r", encoding="utf8") as f:  # 打开文件
                data = f.read()  # 读取文件
                self.textBrowser.append(data)
        except Exception as e:
            self.textBrowser.clear()
            QMessageBox.warning(self, "提示", "请选择正确的升级包文件夹", QMessageBox.Yes)

    def writeConfig(self, **kwargs):
        logger.warn('**************UPGRADE WIRTE INFO**************')
        logger.info(kwargs['host'])
        logger.info(kwargs['user'])
        logger.info(kwargs['port'])
        logger.info(kwargs['password'])
        logger.info(kwargs['local_path'])
        logger.info(kwargs['remote_path'])
        logger.warn('**************END**************')
        """写入配置文件中"""
        try:
            host = kwargs['host'] if 'host' in kwargs else ['192.168.1.150']
            user = kwargs['user'] if 'user' in kwargs else 'pi'
            port = kwargs['port'] if 'port' in kwargs else '22'
            password = kwargs['password'] if 'password' in kwargs else 'raspberry'
            local_path = kwargs['local_path'] if 'local_path' in kwargs else './packages'
            remote_path = kwargs['remote_path'] if 'remote_path' in kwargs else '/home/pi/fsc-system'
            path = '%s/conf/fab.ini' % os.getcwd()
            logger.info('read config file: %s' % path)
            config = configparser.ConfigParser()
            config.read(path)
            config.set("fab", "host", host)
            config.set("fab", "port", port)
            config.set("fab", "user", user)
            config.set("fab", "password", password)
            config.set("fab", "local_path", local_path)
            config.set("fab", "remote_path", remote_path)
            # 写入并保存文件到当前项目文件夹下
            with open(path, 'w') as fw:
                config.write(fw)
        except Exception as e:
            print(e)


if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    win = MainWindow()
    win.show()
    app.exec_()
